<?php

namespace app\index\controller\v1;

use common\helper\CurlHelper;

;

class UserToken extends Token
{

    protected $code;
    protected $wxLoginUrl;
    protected $wxAppID;
    protected $wxAppSecret;
    protected $grant_type;
    protected $open_id;
    protected $user_id;
    protected $token;
    protected $wx_ret_arr;

    function __construct($code)
    {
        $this->code = $code;
        $this->wxAppID = config('wx.app_id');
        $this->wxAppSecret = config('wx.app_secret');
        $this->grant_type = config('wx.grant_type');
        $this->wxLoginUrl = sprintf(
            config('wx.login_url'), $this->wxAppID, $this->wxAppSecret, $this->code, $this->grant_type);
    }

    public function getAndSave()
    {
//        向微信服务端请求openid,返回结果是json字符串
        $result = CurlHelper::curl_get($this->wxLoginUrl);
        $wx_arr = json_decode($result, true);
        if (empty($wx_arr)) {
            throw new Exception('获取session_key及openID时异常，微信内部错误');
        } else {
            $login_fail = array_key_exists('errcode', $wx_arr);
            if ($login_fail) {
                $this->processLoginError($wx_arr);
            } else {
//                生成token
                $token = $this->grantToken();
//                保存token
                $token = $this->saveToken($wx_arr);
                return $token;
            }
        }
    }

    private function duplicateFetch()
    {

    }

    /**
     *  处理微信登陆异常
     * 那些异常应该返回客户端，那些异常不应该返回客户端
     * 需要认真思考
     */
    private function processLoginError($wx_arr)
    {
        $option = [
            'msg' => $wx_arr['errmsg'],
            'errorCode' => $wx_arr['errcode']
        ];
        throw new WeChatException($option);
    }

    private function grantToken()
    {
        $this->token = generateToken(getRandChar(32));
        return $this->token;
    }

    /**
     * 保存token到缓存
     * @return type
     * @throws TokenException
     */
    public function saveToken($wx_arr)
    {
        $this->wx_ret_arr = $wx_arr;
        $this->openid = $wx_arr['openid'];
        $this->user_id = $this->getUserID($this->openid);
        $this->wx_ret_arr['uid'] = $this->user_id;
        $this->wx_ret_arr['scope'] = ScopeEnum::User;
//        序列化
        $expire_in = config('setting.token_expire_in');
        $result = cache($this->token, $this->wx_ret_arr, $expire_in);
        if (!$result) {
            $option = [
                'msg' => '服务器缓存异常',
                'errorCode' => 10005
            ];
            throw new TokenException($option);
        }
        return $this->token;
    }

    /**
     * 通过openid获取userid,没有就新建
     * @param type $openid
     * @return type
     */
    private function getUserID($openid)
    {
        $user_one = UserModel::getOneByOpendId($openid);
        if (empty($user_one)) {
            $user_one = UserModel::CreateByOpendId($openid);
        }
        return $user_one->id;
    }

}
